package server;
import lagern.*;

import java.util.*;
import java.util.Map.Entry;

import org.omg.CORBA.*;
import org.omg.CosNaming.*;
//import org.omg.CosNaming.NamingContextPackage.*;
import org.omg.PortableServer.*;

public class LagerImpl extends LagerPOA{
	@SuppressWarnings({ "rawtypes", "unchecked" })
	Map<String, Fach> faecher  = Collections.synchronizedMap( new HashMap() );
	LinkedList<Monitor> monitore = new LinkedList<Monitor>();
	protected ORB orb; 
	protected Thread shutdownHook; 
	private End e;
		
	public Fach neu(String user,  String name ) throws lagern.LagerPackage.exAlreadyExists {
		if(faecher.containsKey(name)) {
			
			System.out.println("Lager besitzt bereits ein Lagerfach: " + name + " Anfrage von: " + user);
			printMonitor(user, "Lager " + name + " exsitiert bereits");
			throw new lagern.LagerPackage.exAlreadyExists("Lagerfach " + name + " exsistiert bereits"); 

		}
		else {
			System.out.println("Lagerfach besitzt nicht das Lagerfach: " + name + " Anfrage von: " + user);
			printMonitor(user, "Lager " + name + "wird angelegt");
		}
		FachImpl fach = new FachImpl(name,this);
		Fach href = null;
		
		try {
			//POA rootPoa = POAHelper.narrow(Server.orb.resolve_initial_references("RootPOA"));
			org.omg.CORBA.Object ref = Server.rootPoa.servant_to_reference(fach);
			href = FachHelper.narrow(ref);
	
		}catch (Exception e) {
			System.err.println("ERROR: " + e);
			e.printStackTrace(System.out);	
		}
		faecher.put(fach.name(), href);
		//monitor.aktion(name + " erstellt");
		printMonitor(user,"Lagerfach " + name + " erstellt");
		return href;
	}
	
	public Fach hole( String user, String name ) throws lagern.LagerPackage.exNotFound {
		
		if(faecher.containsKey(name))
			return faecher.get(name);
		else 
			throw new lagern.LagerPackage.exNotFound("Lagerfach " + name + " nicht gefunden");
	}
	
	public Fach[] holeLagerListe(){
		Fach[] sv = new Fach[faecher.size()];

		int i = 0;
		for(Iterator<Entry<String, Fach>> it = faecher.entrySet().iterator();it.hasNext();i++) {
			sv[i] =  it.next().getValue();
		}
		return sv;
	}
	
	protected void printMonitor(String user, String str) {
		for(int i = 0;i < monitore.size();i++) {
			try {
				monitore.get(i).aktion(user, str);
			}catch(IndexOutOfBoundsException e) {
				System.err.println(e.toString());
			}
		} 
	}
	
	public void aktiviereMonitor( Monitor monitor ){
		monitore.add(monitor);
		System.out.println("Monitor hinzugefuegt Monitore:" + monitore.size());
	}
	
    public void entferneMonitor( Monitor monitor ){
    	monitore.remove(monitor);
    	System.out.println("Monitor entfernt Monitore:" + monitore.size());
    }
    
    public void quit() {
    	Runtime.getRuntime().removeShutdownHook(shutdownHook);
    	e = new End(orb); 	
    	beendeMonitore();
    	e.start();
    }
    
    protected void beendeMonitore(){
    	while(monitore.size() > 0){
    		Monitor mon = null;
    		mon = monitore.pop();
    		mon.quit();
    	}
	}
}
